package bairui.international.service.impl;

import java.util.Date;
import java.util.List;

import javax.persistence.LockModeType;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.lianjing.sh.project.common.service.Service_Number;
import com.lianjing.sh.validate.spring.exception.ValidateObjectException;
import com.sh_lianjing.state.StateTransition;

import bairui.international.model.domain.jpa.TB_ElectronicTicket;
import bairui.international.model.domain.jpa.TB_ElectronicTicketOrder;
import bairui.international.model.domain.jpa.TB_ProductOrder;
import bairui.international.model.domain.jpa.TB_User;
import bairui.international.model.status.State_ElectronicTicket;
import bairui.international.service.Service_ElectronicTicket;
import bairui.international.service.Service_ElectronicTicketStateRecord;
import bairui.international.service.Service_User;

/**
 * 
 * 【(电子券)TB_ElectronicTicket】服务实现
 *
 * @generated
 * 
 * @see bairui.international.model.domain.jpa.TB_ElectronicTicket 模型
 * @see Service_ElectronicTicket 服务接口
 * @see BService_ElectronicTicketImpl 服务实现基础
 *
 */
@Service
public class Service_ElectronicTicketImpl extends BService_ElectronicTicketImpl implements Service_ElectronicTicket {

	@Autowired private Service_Number service_Number;
	@Autowired private Service_ElectronicTicketStateRecord service_ElectronicTicketStateRecord;
	@Autowired private Service_User service_user;
	private final String ElectronicTicketNumber = "ElectronicTicketNumber";
	
	@Override
	public TB_ElectronicTicket newInstance(TB_ElectronicTicketOrder bean) {
		return dao.save(new TB_ElectronicTicket(new TB_ElectronicTicket(
				new TB_ElectronicTicket.MustProperties() {
					@Override public State_ElectronicTicket getState() {
						return State_ElectronicTicket.t_generate().to();
					}
					@Override public String getNumber() {
						return service_Number.generateDateFormatNumber(ElectronicTicketNumber);
					}
					@Override public TB_ElectronicTicketOrder getElectronicTicketOrder() {
						return bean;
					}
					@Override public Integer getTransmitCount() {
						return 0;
					}
				}, 
				new TB_ElectronicTicket.OptionalSingleProperties() {
					@Override public TB_User getAssignedUser() {
						return null;
					}
					@Override public TB_User getTakor() {
						return null;
					}
					@Override public Date getAssignDate() {
						return null;
					}
					@Override public Date getUseDate() {
						return null;
					}
					@Override public Date getTakeDate() {
						return null;
					}
					@Override public TB_ProductOrder getProductOrder() {
						return null;
					}
					@Override public String getDimensionalUrl() {
						return null;
					}
				}
			)));
	}

	@Override
	public void assign(List<Long> ids, long userId) throws Exception {
		for(Long id : ids){
			TB_ElectronicTicket bean = load(new TB_ElectronicTicket(id));
			// 处理数据
			StateTransition<State_ElectronicTicket> trans = null;
			if(bean.getElectronicTicketOrder().getGiveFlag()){
				trans = bean.new UpdateProperties() {
					StateTransition<State_ElectronicTicket> trans;
					@Override public State_ElectronicTicket getState(TB_ElectronicTicket it) throws Exception {
						trans = it.getState().t_assign_from_Generated();
						return trans.to();
					}
					@Override public Date getAssignDate(TB_ElectronicTicket it) throws Exception {
						return new Date();
					};
					@Override public TB_User getAssignedUser(TB_ElectronicTicket it) throws Exception {
						return new TB_User(userId);
					};
				}.trans;
			}else{
				trans = bean.new UpdateProperties() {
					StateTransition<State_ElectronicTicket> trans;
					@Override public State_ElectronicTicket getState(TB_ElectronicTicket it) throws Exception {
						trans = it.getState().t_take_from_Generated();
						return trans.to();
					}
					@Override public Date getTakeDate(TB_ElectronicTicket it) throws Exception {
						return new Date();
					};
					@Override public TB_User getTakor(TB_ElectronicTicket it) throws Exception {
						return new TB_User(userId);
					};
				}.trans;
			}
			// 处理记录
			service_ElectronicTicketStateRecord.createFlowRecord(bean, trans.comment());
		}
	}

	@Override
	public TB_ElectronicTicket accept(long id, String skey) throws Exception {
		TB_ElectronicTicket bean = findByIdUseLock(id);
		// 验证
		if(bean.getState() != State_ElectronicTicket.Assigned){
			throw new ValidateObjectException("object", "", "已被领取");
		}
		if(bean.getAssignedUser().getSkey().equals(skey)){
			throw new ValidateObjectException("object", "", "不能领取自己赠出的券");
		}
		TB_ElectronicTicketOrder order = bean.getElectronicTicketOrder();
		if(!order.getAgainFlag() && exists(it->it.takor.skey.eq(skey).and(it.takor.takedTickets.any().electronicTicketOrder.eq(order)))){
			throw new ValidateObjectException("object", "", "已领券,不能再次领取");
		}
		if(order.getOneuseFlag() && exists(it->it.takor.skey.eq(skey).and(it.takor.takedTickets.any().electronicTicketOrder.oneuseFlag.eq(true)))){
			throw new ValidateObjectException("object", "", "只能领取一次,不能再次领取");
		}
		// 处理数据
		TB_User user = service_user.findOne(it->it.skey.eq(skey));
		StateTransition<State_ElectronicTicket> trans = bean.new UpdateProperties() {
			StateTransition<State_ElectronicTicket> trans;
			@Override public State_ElectronicTicket getState(TB_ElectronicTicket it) throws Exception {
				trans = it.getState().t_take_from_Assigned();
				return trans.to();
			}
			@Override public Date getTakeDate(TB_ElectronicTicket it) throws Exception {
				return new Date();
			};
			@Override public TB_User getTakor(TB_ElectronicTicket it) throws Exception {
				return user;
			};
		}.trans;
		// 处理记录
		service_ElectronicTicketStateRecord.createFlowRecord(bean, trans.comment());
		//
		return bean;
	}
	
	/**
	 * 通过名称查找（加锁）
	 */
	private TB_ElectronicTicket findByIdUseLock(Long id){
		return dao
				.find(QRoot.id.eq(id))
				.setLockMode(LockModeType.PESSIMISTIC_READ)
				.oneResult();
	}

	@Override
	public TB_ElectronicTicket use(long id, TB_ProductOrder order) throws Exception {
		TB_ElectronicTicket bean = findByIdUseLock(id);
		StateTransition<State_ElectronicTicket> trans = bean.new UpdateProperties() {
			StateTransition<State_ElectronicTicket> trans;
			@Override public State_ElectronicTicket getState(TB_ElectronicTicket it) throws Exception {
				trans = it.getState().t_use_to_Used();
				return trans.to();
			}
			@Override public Date getUseDate(TB_ElectronicTicket it) throws Exception {
				return new Date();
			};
			@Override public TB_ProductOrder getProductOrder(TB_ElectronicTicket it) throws Exception {
				return order;
			};
		}.trans;
		// 处理记录
		service_ElectronicTicketStateRecord.createFlowRecord(bean, trans.comment());
		//
		return bean;
	}

	@Override
	public void setDimensionalUrl(Long id, String dimensionalUrl) throws Exception {
		findById(id).setDimensionalUrl(dimensionalUrl);
	}

	@Override
	public TB_ElectronicTicket cancel(long id) throws Exception {
		TB_ElectronicTicket bean = findById(id);
		// 处理数据
		StateTransition<State_ElectronicTicket> trans = bean.new UpdateProperties() {
			StateTransition<State_ElectronicTicket> trans;
			@Override public State_ElectronicTicket getState(TB_ElectronicTicket it) throws Exception {
				trans = it.getState().t_cancel_to_Canceled();
				return trans.to();
			}
		}.trans;
		// 处理记录
		service_ElectronicTicketStateRecord.createFlowRecord(bean, trans.comment());
		//
		return bean;
	}

}
